package 剑指offer;

public class _56数组中出现一次的数字 {
    // 从头到尾异或所有数，得到的结果是两个只出现一次数字的数的异或结果
    // 找到第一个位异或结果为 1 的位，说明在这一位两位数的高低不同，
    // 而相同的数也会被有效的分到同一组中
    public int[] singleNumbers(int[] nums) {
        int sum = 0;
        for (int num : nums) {
            sum ^= num;
        }
        int h = 1;
        // 细节： == 号实际上是比 & 优先级高的
        while ((h & sum) == 0){
            h <<= 1;
        }
        // 分组
        int group1 = 0, group2 = 0;
        for (int num : nums) {
            if ((num & h) == 0){
                group1 ^= num;
            }else {
                group2 ^= num;
            }
        }
        return new int[]{group1, group2};
    }


}
